/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dao;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

import util.HibernateUtil;

public abstract class AbstractDAO<P, K extends Serializable> {

	protected abstract Class getPOJOClass();

	protected abstract Query MakeHQL();

	public synchronized P getByHQL(K key) throws HibernateException {
		P p = null;
		Session session = HibernateUtil.getSessionFactory().openSession();
		try {
			Query query = MakeHQL();
			p = (P) query.uniqueResult();
		} catch (HibernateException ex) {
			System.err.println(ex);
		} finally {
			session.close();
		}
		return p;
	}

	public synchronized P get(K key) throws HibernateException {
		if (key != null) {
			Session session = HibernateUtil.getSessionFactory().openSession();
			P p = (P) session.get(getPOJOClass(), key);
			session.close();
			return p;
		}
		return null;
	}

	public synchronized List<P> getList() throws HibernateException {
		Session session = HibernateUtil.getSessionFactory().openSession();
		String hql = String.format("select obj from %s obj", getPOJOClass()
				.getName());
		Query query = session.createQuery(hql);
		List<P> list = query.list();
		session.close();
		return list;
	}

	public synchronized void saveOrUpdate(P p) throws HibernateException {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction trans = session.beginTransaction();
		try {
			session.saveOrUpdate(p);
			trans.commit();
		} catch (HibernateException ex) {
			trans.rollback();
			throw ex;
		} finally {
			session.close();
		}
	}

	public synchronized void delete(P p) throws HibernateException {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction trans = session.beginTransaction();
		try {
			session.delete(p);
			trans.commit();
		} catch (HibernateException ex) {
			trans.rollback();
			throw ex;
		} finally {
			session.close();
		}
	}

	// ---------------------
	public List<P> removeDuplicate(List<P> list) throws HibernateException {

		Set<P> s = new LinkedHashSet<P>(list);
		List<P> result = new ArrayList<P>(s);
		return result;
	}
}
